var App = (function(App, $, _){

	'user strict';

	var host = {};
	var moduleName = "host"; // define a unique module name

	host.gameStatus = {}; // hold the current game status

	host.startGame = function() {

		var participants;
		var participant;

		participants = gapi.hangout.getEnabledParticipants();

		host.gameStatus = {};

		// default the card choice of each participant to null
		for(var i=0; i < participants.length; i++) {
			participant = participants[i];
			host.gameStatus[participant.id] = {
				cardSelected: null,
				ts: null
			};
		}

		App.log("HOST gameStarted", host.gameStatus);

		currentGameState = gapi.hangout.data.getValue("gameState");
		if(currentGameState != "started"){
			gapi.hangout.data.setValue("gameState","started");
		}

		gapi.hangout.data.sendMessage(JSON.stringify({
			event: "gameStarted",
			data: {
				gameStatus: host.gameStatus
			}
		}));		
	};

	host.updateGame = function(participantStatus) {

		if(host.gameStatus.hasOwnProperty(participantStatus.participantId)) {
			
			host.gameStatus[participantStatus.participantId] = {
				cardSelected: participantStatus.cardSelected,
				ts: participantStatus.ts
			};

			App.log("HOST gameUpdated", host.gameStatus);

			gapi.hangout.data.sendMessage(JSON.stringify({
				event: "gameUpdated", 
				data: { gameStatus: host.gameStatus }
			}));

			host.isGameFinished();

		} else {
			// user is not in the current game
			// or a game hasn't been started
		}

	};

	host.isGameFinished = function() {
		var cardsSelectedCount = 0;
		var participantsCount = host.gameStatus.length;
		_.each(host.gameStatus, function(participantStatus, participantId){
			if(participantStatus.cardSelected !== null){
				cardsSelectedCount++;
			}
		});
		if(participantsCount <= cardsSelectedCount) {
			host.finishGame();
		}
	};

	host.finishGame = function() {

		App.log("HOST gameFinished", host.gameStatus);

		gapi.hangout.data.setValue("gameData",JSON.stringify(host.gameStatus));
		currentGameState = gapi.hangout.data.getValue("gameState");
		if(currentGameState != "finished"){
			gapi.hangout.data.setValue("gameState","finished");
		}

		gapi.hangout.data.sendMessage(JSON.stringify({
			event: "gameFinished",
			data: {
				gameStatus: host.gameStatus
			}
		}));

	};

	host.parseMessage = function(message) {
		var msg = JSON.parse(message.message);
		var participantStatus = {};
		console.log("HOST message received, is it gameParticipantStatus?", msg.event);
		if(msg.hasOwnProperty("event")) {
			if(msg.event === "gameParticipantStatus") {
				participantStatus.cardSelected = msg.data.cardSelected;
				participantStatus.participantId = msg.data.participantId;
				participantStatus.ts = (new Date()).getTime();			
				host.updateGame(participantStatus);
			}
		}
	};

	host.bindEvents = function() {

		// listen for user status
		gapi.hangout.data.onMessageReceived.add(host.parseMessage);

		// at any time host can reveal/reset game
		App.on("startGame", host.startGame);
		App.on("finishGame", host.finishGame);

	};

	// default initialisation method (called when API and DOM are ready)
	host.init = function() {
		if( App.isHost() === true) {
			console.log("binding host events");
			host.bindEvents();
		}
	};

	/* ================================ */

	// add module to list of modules
	App.modules = App.hasOwnProperty("modules") ? App.modules : {};
	App.modules[moduleName] = host;

	return App;

}(App || {}, $, _));